<template>
  <view
    class="tn-badge"
    :class="[badgeClass]"
    :style="badgeStyle"
    @tap.stop="handleClick"
  >
    <template v-if="dot"></template>
    <view v-else class="tn-badge__content">
      <slot></slot>
    </view>
  </view>
</template>

<script lang="ts" setup>
import { badgeProps, badgeEmits } from '../../../types/tn-badge'
import { TuniaoSize, TuniaoSizes } from '../../../types/tuniao-ui'
import { computed, watchEffect, CSSProperties } from 'vue'
import useComponentColor from '../../../libs/hooks/useComponentColor'
import { handleValueWithUnit } from '../../../utils'

const props = defineProps(badgeProps)
const emits = defineEmits(badgeEmits)

const { generateColorInfo } = useComponentColor()
let componentColorInfo = generateColorInfo(props?.color || '', props?.bgColor || '')
// 监听颜色变化实时修改颜色对应的属性
watchEffect(() => {
  componentColorInfo = generateColorInfo(props?.color || '', props?.bgColor || '')
})

// 微标样式
const badgeStyle = computed<CSSProperties>(() => {
  let style: CSSProperties = {}

  // 如果size不在默认size值中则是自定义size
  if (!!props.size && !TuniaoSizes.includes(props.size as TuniaoSize)) {
    style.width = handleValueWithUnit(props.size)
    if (props?.dot) {
      style.height = style.width
    }
  }
  if (props?.fontSize) {
    style.fontSize = handleValueWithUnit(props.fontSize)
  }

  if (componentColorInfo.style?.color) {
    style.color = componentColorInfo.style.color
  }
  if (componentColorInfo.style?.backgroundColor) {
    style.backgroundColor = componentColorInfo.style.backgroundColor
  }

  // 如果是绝对定位，则设置绝对定位的偏移数据
  if (props?.absolute) {
    const positionKeys = Object.keys(props?.absolutePosition || {})
    // 先做判断防止出现其他参数
    if (positionKeys.every((item) => {
      return ['top', 'right'].includes(item)
    })) {
      style = Object.assign(style, props?.absolutePosition || {
        top: '0rpx',
        right: '0rpx'
      })
    }
  }

  return Object.assign(style, props.customStyle || {})
})

// badge对应类
const badgeClass = computed<string>(() => {
  let clazz: string[] = []

  if (componentColorInfo.class.length > 0) {
    clazz.push(...componentColorInfo.class)
  }

  if (!!props.size && TuniaoSizes.includes(props.size as TuniaoSize)) {
    clazz.push(`tn-badge--${props.size}`)
  }
  if (!!props?.type) {
    clazz.push(`tn-type-${props.type}`)
  }

  if (props?.absolute) {
    clazz.push('tn-badge--absolute')
    if (props?.absoluteCenter) {
      clazz.push('tn-badge--absolute--center')
    }
  }

  if (props?.dot) {
    clazz.push('tn-badge--dot')
  }

  return clazz.join(' ')
})

// 处理点击事件
const handleClick = () => {
  emits('click', props?.index)
}

</script>

<script lang="ts">
export default {
  options: {
    // 在微信小程序中将组件节点渲染为虚拟节点，更加接近Vue组件的表现(不会出现shadow节点下再去创建元素)
    virtualHost: true
  }
}
</script>

<style lang="scss" scoped>
@import '../../../theme.scss';
.tn-badge {
  position: relative;
  background-color: $tn-main-color;
  color: #FFFFFF;
  width: fit-content;
  border-radius: 1000rpx;
  font-size: 20rpx;
  padding: 2rpx 6rpx;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  line-height: 1;

  &__content {
    // 设置了display: contents的元素本身不会被渲染，但是其子元素能够正常被渲染
    display: contents;
    // font-size: initial;
    line-height: 1;
  }

  &--dot {
    width: 20rpx;
    height: 20rpx;
    border-radius: 50%;
    padding: 0;
  }

  &--absolute {
    position: absolute;
    top: 0;
    right: 0;

    &--center {
      transform: translate(50%, -50%);
    }
  }

  /* 内置尺寸 start */
  &--sm {
    font-size: 14rpx;
    padding: 2rpx 4rpx;
    &.tn-badge--dot {
      width: 14rpx;
      height: 14rpx;
      padding: 0;
    }
  }
  &--lg {
    font-size: 24rpx;
    padding: 2rpx 6rpx;
    &.tn-badge--dot {
      width: 30rpx;
      height: 30rpx;
      padding: 0;
    }
  }
  &--xl {
    font-size: 28rpx;
    padding: 2rpx 8rpx;
    &.tn-badge--dot {
      width: 40rpx;
      height: 40rpx;
      padding: 0;
    }
  }
  /* 内置尺寸 end */
}
</style>
